﻿using System;
using System.Collections;
using System.Collections.Generic;
using Me.Prettyprint.Cassandra.Connection;
using Me.Prettyprint.Cassandra.Service;
using Me.Prettyprint.Cassandra.Serializers;
using Me.Prettyprint.Cassandra.Utils;
using Me.Prettyprint.Hector.Api;
using Me.Prettyprint.Hector.Api.Beans;
using Me.Prettyprint.Hector.Api.Query;
using Org.Apache.Cassandra.Thrift;
using Thrift;

namespace Me.Prettyprint.Cassandra.Model
{
    /// <summary>
    /// CqlQuery uses CqlQueryOperation to execute the actual query. CqlQueryOperation is
    /// responsible for knowing how to handle CQL version and read the result.
    /// </summary>
    /// <typeparam name="K"></typeparam>
    /// <typeparam name="N"></typeparam>
    /// <typeparam name="V"></typeparam>
    public class CqlQuery<K, N, V> : AbstractBasicQuery<K, N, CqlRows<K, N, V>>
    {
        private static Logger log = new Logger(typeof(CqlQuery<K, N, V>));
        public CqlQuery(Keyspace k, Serializer<K> keySerializer,
            Serializer<N> nameSerializer, Serializer<V> valueSerializer) : base(k, keySerializer, nameSerializer)
        {
            ValueSerializer = valueSerializer;
            cql3 = false;
        }

        protected Serializer<V> ValueSerializer
        {
            get;
            set;
        }
        protected byte[] Query
        {
            get;
            set;
        }
        protected bool Compression
        {
            get;
            set;
        }
        protected bool SuppressKeyInColumns
        {
            get;
            set;
        }
        protected bool cql3
        {
            get;
            set;
        }
        public CqlQuery<K, N, V> SetQuery(string query)
        {
            Query = StringSerializer.Instance.ToBytes(query);
            return this;
        }

        public CqlQuery<K, N, V> SetQuery(ByteBuffer qeury)
        {
            Query = qeury.GetBuffer();
            return this;
        }
        public CqlQuery<K, N, V> SetCqlVersion(string version)
        {
            CqlVersion = version;
            return this;
        }
        public CqlQuery<K, N, V> SetSuppressKeyInColumns(bool suppressKeyInColumns)
        {
            SuppressKeyInColumns = suppressKeyInColumns;
            return this;
        }
        public CqlQuery<K, N, V> UseCompression()
        {
            Compression = true;
            return this;
        }
        public override QueryResult<CqlRows<K, N, V>> Execute()
        {
            CqlQueryOperation<K, N, V> operation = new CqlQueryOperation<K, N, V>(OperationType.READ, CqlVersion, Compression,
                Query, Keyspace, KeySerializer, ColumnNameSerializer, ValueSerializer, SuppressKeyInColumns);
            operation.ConsistencyLevel = ConsistencyLevel;
            ExecutionResult<CqlRows<K, N, V>> execRes = Keyspace.DoExecuteOperation<CqlRows<K, N, V>>(operation);
            QueryResultImpl<CqlRows<K, N, V>> result = new QueryResultImpl<CqlRows<K, N, V>>(execRes, this);
            return result;
        }  

    }
}
